using Microsoft.Extensions.Caching.Memory;
using System;

namespace LiJ.Common.Plugs.CachePlug
{
	/// <summary>
	///
	/// </summary>
	public class DefaultCachePlug : ICachePlug
	{
		private static readonly MemoryCache MCache = new MemoryCache(new MemoryCacheOptions());

		/// <summary>
		/// 添加缓存
		/// 如果存在则更新
		/// </summary>
		/// <typeparam name="T">添加缓存对象类型</typeparam>
		/// <param name="key">添加对象的key</param>
		/// <param name="obj">值</param>
		/// <param name="slidingExpiration">相对过期的TimeSpan  如果使用固定时间  =TimeSpan.Zero</param>
		/// <param name="absoluteExpiration"> 绝对过期时间,不为空则按照绝对过期时间计算 </param>
		/// <returns>是否添加成功</returns>
		[Obsolete]
		public bool AddOrUpdate<T>(string key, T obj, TimeSpan slidingExpiration, DateTime? absoluteExpiration = default(DateTime?))
		{
			return Add(key, obj, slidingExpiration, absoluteExpiration);
		}

		/// <summary> 
		/// 添加时间段过期缓存
		/// 如果存在则更新
		/// </summary>
		/// <typeparam name="T">添加缓存对象类型</typeparam>
		/// <param name="key">添加对象的key</param>
		/// <param name="obj">值</param>
		/// <param name="slidingExpiration">相对过期的TimeSpan</param>
		/// <returns>是否添加成功</returns>
		public bool Set<T>(string key, T obj, TimeSpan slidingExpiration)
		{
			return Add(key, obj, slidingExpiration, null);
		}

		/// <summary>
		/// 添加固定过期时间缓存,如果存在则更新
		/// </summary>
		/// <typeparam name="T">添加缓存对象类型</typeparam>
		/// <param name="key">添加对象的key</param>
		/// <param name="obj">值</param>
		/// <param name="absoluteExpiration"> 绝对过期时间,不为空则按照绝对过期时间计算 </param>
		/// <returns>是否添加成功</returns>
		public bool Set<T>(string key, T obj, DateTime absoluteExpiration)
		{
			return Add(key, obj, TimeSpan.Zero, absoluteExpiration);
		}

	    ///  <summary>
	    /// 
	    ///  </summary>
	    ///  <typeparam name="T"></typeparam>
	    ///  <param name="key"></param>
	    ///  <param name="obj"></param>
	    ///  <param name="slidingExpiration"></param>
	    ///  <param name="absoluteExpiration"></param>
	    /// <returns></returns>
	    private static bool Add<T>(string key, T obj, TimeSpan slidingExpiration, DateTime? absoluteExpiration)
		{
			if (slidingExpiration == TimeSpan.Zero && !absoluteExpiration.HasValue)
			{
				throw new ArgumentNullException("slidingExpiration", "缓存过期时间不正确,需要设置固定过期时间或者相对过期时间");
			}
			MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions();
			if (absoluteExpiration.HasValue)
			{
				memoryCacheEntryOptions.AbsoluteExpiration = new DateTimeOffset(absoluteExpiration.Value);
			}
			else
			{
				memoryCacheEntryOptions.SlidingExpiration = slidingExpiration;
			}
            MCache.Set(key, obj, memoryCacheEntryOptions);
			return true;
		}

		/// <inheritdoc />
		/// <summary>
		/// 获取缓存对象
		/// </summary>
		/// <typeparam name="T">获取缓存对象类型</typeparam>
		/// <param name="key">key</param>
		/// <returns>获取指定key对应的值 </returns>
		public T Get<T>(string key)
		{
			return MCache.Get<T>(key);
		}

		/// <inheritdoc />
		/// <summary>
		/// 移除缓存对象
		/// </summary>
		/// <param name="key"></param>
		/// <returns>是否成功</returns>
		public bool Remove(string key)
		{
            MCache.Remove(key);
			return true;
		}
	}
}
